package cn.harry.cabinet.repository

import android.app.Application
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import cn.harry.cabinet.api.ExternalApiService
import cn.harry.cabinet.api.enums.ExternalServiceType
import cn.harry.cabinet.database.AppDatabase
import cn.harry.cabinet.model.entity.User
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
 * 用户数据仓库
 * 管理用户数据的获取和操作
 */
@OptIn(DelicateCoroutinesApi::class)
class UserRepository(application: Application) : BaseRepository() {
    
    private val userDao = AppDatabase.getDatabase(application).userDao()
    private val externalApiService = ExternalApiService.getInstance(application)
    private val users = MutableLiveData<List<User>>()
    private val totalCount = MutableLiveData<Int>()
    
    // 分页相关参数
    private var currentPage = 0
    private val pageSize = 20 // 每页显示20条记录
    private var currentQuery = ""
    private var hasMoreData = true
    
    init {
        // 初始化用户数据
        kotlinx.coroutines.GlobalScope.launch {
            loadUsersWithPagination()
        }
    }
    
    /**
     * 获取所有用户
     */
    fun getUsers(): LiveData<List<User>> {
        return users
    }
    
    /**
     * 直接获取所有用户（同步方法）
     */
    suspend fun getAllUsers(): List<User> {
        return withContext(Dispatchers.IO) {
            try {
                userDao.getAllUsers()
            } catch (e: Exception) {
                throw Exception("获取所有用户失败: ${e.message}")
            }
        }
    }
    
    /**
     * 获取总用户数
     */
    fun getTotalCount(): LiveData<Int> {
        return totalCount
    }
    
    /**
     * 检查是否还有更多数据
     */
    fun hasMoreData(): Boolean = hasMoreData
    
    /**
     * 重置分页状态
     */
    fun resetPagination() {
        currentPage = 0
        hasMoreData = true
    }
    
    /**
     * 搜索用户
     */
    suspend fun searchUsers(query: String) {
        currentQuery = query
        resetPagination()
        if (query.isBlank()) {
            loadUsersWithPagination()
        } else {
            loadSearchResultsWithPagination(query)
        }
    }
    
    /**
     * 刷新用户数据
     */
    suspend fun refreshUsers() {
        resetPagination()
        currentQuery = ""
        loadUsersWithPagination()
    }
    
    /**
     * 加载更多用户数据
     */
    suspend fun loadMoreUsers() {
        if (!hasMoreData) return
        
        currentPage++
        if (currentQuery.isBlank()) {
            loadUsersWithPagination()
        } else {
            loadSearchResultsWithPagination(currentQuery)
        }
    }
    
    /**
     * 添加新用户
     */
    suspend fun addUser(user: User): User {
        return withContext(Dispatchers.IO) {
            try {
                val insertedId = userDao.insertUser(user)
                val newUser = user.copy(id = insertedId)
                resetPagination()
                loadUsersWithPagination()
                
                // 通知外部接口
                externalApiService.notifyUserOperation(newUser, ExternalServiceType.ADD_USER)
                
                newUser
            } catch (e: Exception) {
                throw Exception("添加用户失败: ${e.message}")
            }
        }
    }
    
    /**
     * 更新用户
     */
    suspend fun updateUser(user: User) {
        withContext(Dispatchers.IO) {
            try {
                userDao.updateUser(user)
                resetPagination()
                loadUsersWithPagination()
                
                // 通知外部接口
                externalApiService.notifyUserOperation(user, ExternalServiceType.UPDATE_USER)
            } catch (e: Exception) {
                throw Exception("更新用户失败: ${e.message}")
            }
        }
    }
    
    /**
     * 删除用户
     */
    suspend fun deleteUser(user: User) {
        withContext(Dispatchers.IO) {
            try {
                userDao.deleteUser(user)
                resetPagination()
                loadUsersWithPagination()
                
                // 通知外部接口
                externalApiService.notifyUserOperation(user, ExternalServiceType.DELETE_USER)
            } catch (e: Exception) {
                throw Exception("删除用户失败: ${e.message}")
            }
        }
    }
    
    /**
     * 分页加载用户数据
     */
    private suspend fun loadUsersWithPagination() {
        withContext(Dispatchers.IO) {
            try {
                val total = userDao.getUserCount()
                val offset = currentPage * pageSize
                val userList = userDao.getUsersWithPagination(pageSize, offset)
                
                withContext(Dispatchers.Main) {
                    if (currentPage == 0) {
                        // 第一页，直接设置数据
                        users.value = userList
                    } else {
                        // 加载更多，追加数据
                        val currentUsers = users.value.orEmpty().toMutableList()
                        currentUsers.addAll(userList)
                        users.value = currentUsers
                    }
                    
                    totalCount.value = total
                    hasMoreData = (offset + pageSize) < total
                }
            } catch (e: Exception) {
                e.printStackTrace()
                throw Exception("加载用户数据失败: ${e.message}")
            }
        }
    }
    
    /**
     * 分页加载搜索结果
     */
    private suspend fun loadSearchResultsWithPagination(query: String) {
        withContext(Dispatchers.IO) {
            try {
                val total = userDao.getSearchUserCount(query)
                val offset = currentPage * pageSize
                val searchResults = userDao.searchUsersWithPagination(query, pageSize, offset)
                
                withContext(Dispatchers.Main) {
                    if (currentPage == 0) {
                        // 第一页，直接设置数据
                        users.value = searchResults
                    } else {
                        // 加载更多，追加数据
                        val currentUsers = users.value.orEmpty().toMutableList()
                        currentUsers.addAll(searchResults)
                        users.value = currentUsers
                    }
                    
                    totalCount.value = total
                    hasMoreData = (offset + pageSize) < total
                }
            } catch (e: Exception) {
                e.printStackTrace()
                throw Exception("搜索用户失败: ${e.message}")
            }
        }
    }

    /**
     * 获取搜索结果总数
     */
    suspend fun getSearchUserCount(query: String, offset: Int, size: Int): Long {
        return withContext(Dispatchers.IO) {
            try {
                userDao.getSearchUserCount(query).toLong()
            } catch (e: Exception) {
                throw Exception("获取搜索结果总数失败: ${e.message}")
            }
        }
    }
    
    /**
     * 分页搜索用户
     */
    suspend fun searchUsersWithPagination(query: String, offset: Int, size: Int): List<User> {
        return withContext(Dispatchers.IO) {
            try {
                userDao.searchUsersWithPagination(query, size, offset)
            } catch (e: Exception) {
                throw Exception("分页搜索用户失败: ${e.message}")
            }
        }
    }
    
    /**
     * 根据ID查询用户
     */
    suspend fun getUserById(id: Long): User? {
        return withContext(Dispatchers.IO) {
            try {
                userDao.getUserById(id)
            } catch (e: Exception) {
                throw Exception("查询用户失败: ${e.message}")
            }
        }
    }
    
    /**
     * 根据工号查询用户
     */
    suspend fun getUserByEmployeeId(employeeId: String): User? {
        return withContext(Dispatchers.IO) {
            try {
                userDao.getUserByEmployeeId(employeeId)
            } catch (e: Exception) {
                throw Exception("查询用户失败: ${e.message}")
            }
        }
    }
    

    /**
     * 检查工号是否已存在
     */
    suspend fun isEmployeeIdExists(employeeId: String, excludeUserId: Long = 0): Boolean {
        return withContext(Dispatchers.IO) {
            try {
                val existingUser = userDao.getUserByEmployeeId(employeeId)
                existingUser != null && existingUser.id != excludeUserId
            } catch (e: Exception) {
                throw Exception("检查工号失败: ${e.message}")
            }
        }
    }

    /**
     * 检查特征码是否已存在
     */
    suspend fun isFeatureCodeExists(featureCode: String, excludeUserId: Long = 0): Boolean {
        return withContext(Dispatchers.IO) {
            try {
                val existingUser = userDao.getUserByFeatureCode(featureCode)
                existingUser != null && existingUser.id != excludeUserId
            } catch (e: Exception) {
                throw Exception("检查特征码失败: ${e.message}")
            }
        }
    }
}